package com.itheima.reggie.common;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局的异常捕获类
 * RestControllerAdvice注解ControllerAdvice和ResponseBody的结合体
 * ControllerAdvice这个注解是为了声明@ExceptionHandler注解方法的一个component。说白了就是aop思想（指定拦截那些类型的控制器）
 * 你告诉我需要拦截规则，我帮你拦截下来，具体的实现是通过@ExceptionHandler的注解方法去实现的。
 *ResponseBody将数据转换为JSON数据格式发送给前端页面。
 * annotations = {RestController.class, Controller.class} 这两个类表示拦截所有。
 */
@RestControllerAdvice(annotations = {RestController.class, Controller.class})
public class GlobalExceptionHandler {
    /**
     *ExceptionHandler是一个自定义异常，自定义异常拦截器。得写出要捕获的是那种类型的异常，
     * SQLIntegrityConstraintViolationException这是一个异常类型，捕获mysql表中有unique的字段，还继续添加相同字段的异常。
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
        ex.printStackTrace();
       // ex.getMessage() = Duplicate entry 'admin' for key 'unique_username' -- Duplicate entry是违反字段的唯一性
        String message = ex.getMessage();  //获取异常捕获的错误信息
        if(message.contains("Duplicate entry")){  //判断是否包含Duplicate entry，如果是则是重复添加唯一字段异常。
            String[] s = message.split(" ");
            return R.error(s[2]+"已存在"); //返回的时R对象，没有泛型，但是R<String>也可以接受，返回值写R<String>是一种规范，是一种标识。
        }
       return R.error("未知错误");
    }

    /**
     * ExceptionHandler后面的括号应该是此次所捕获的异常的所属的类型。
     * 写了它异常既可以精确匹配到这个方法，所以这个方法的名字可以相同。
     * @return
     */
    @ExceptionHandler(CustomException.class)
      public R<String> exceptionHandler(CustomException customException){
        //runtimeException是可以通过getMessage获取到异常的信息的。
          return R.error(customException.getMessage());
      }
}
